package cn.hongwei.mall.search.listener;

import cn.hongwei.mall.common.bean.ResponseVo;
import cn.hongwei.mall.pms.entity.*;
import cn.hongwei.mall.search.feign.MallPmsClient;
import cn.hongwei.mall.search.feign.MallWmsClient;
import cn.hongwei.mall.search.pojo.Goods;
import cn.hongwei.mall.search.pojo.SearchAttrValueVo;
import cn.hongwei.mall.search.repository.GoodsRepository;
import cn.hongwei.mall.wms.entity.WareSkuEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Great
 * @email 1224028994@qq.com
 */
@Component
public class GoodsListener {

    @Autowired
    private MallPmsClient mallPmsClient;

    @Autowired
    private GoodsRepository goodsRepository;

    @Autowired
    private MallWmsClient mallWmsClient;

    //ignoreDeclarationExceptions 忽略队列声明异常
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("SEARCH_ITEM_QUEUE")
            ,exchange = @Exchange(value = "PMS_SPU_EXCHANGE",ignoreDeclarationExceptions = "true",type = ExchangeTypes.TOPIC)
            ,key = "item.insert"
    ))
    public void listener(Long spuId, Channel channel, Message message)  {
        if (spuId == null) {
            //说明消息接受失败
            try {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//false表示不批量确认
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        //数据同步
        //根据spuId查询sku
        List<SkuEntity> skuEntities = mallPmsClient.querySkuBySpuId(spuId).getData();
        if (!CollectionUtils.isEmpty(skuEntities)) {
            //根据spuId查询spu，远程调用pms
            SpuEntity spuEntity = mallPmsClient.querySpuById(spuId).getData();
            if(spuEntity==null){
                return;
            }
            //查询品牌
            BrandEntity brandEntity = mallPmsClient.queryBrandById(spuEntity.getBrandId()).getData();
            //查询分类
            CategoryEntity categoryEntity = mallPmsClient.queryCategoryById(spuEntity.getCategoryId()).getData();
            //把sku集合转换成goods集合
            List<Goods> goodsList = skuEntities.stream().map(skuEntity -> {
                Goods goods = new Goods();
                // sku相关信息
                goods.setSkuId(skuEntity.getId());
                goods.setTitle(skuEntity.getTitle());
                goods.setSubTitle(skuEntity.getSubtitle());
                goods.setPrice(skuEntity.getPrice().doubleValue());
                goods.setDefaultImage(skuEntity.getDefaultImage());

                // 新品的spu的创建时间
                goods.setCreateTime(spuEntity.getCreateTime());
                // 库存相关
                ResponseVo<List<WareSkuEntity>> wareResponseVo = mallWmsClient.queryBySkuId(skuEntity.getId());
                List<WareSkuEntity> wareSkuEntities = wareResponseVo.getData();
                if (!CollectionUtils.isEmpty(wareSkuEntities)) {
                    goods.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
                    goods.setSales(wareSkuEntities.stream().map(WareSkuEntity::getSales).reduce((a, b) -> a + b).get());
                }

                // 品牌相关
                if (brandEntity != null) {
                    goods.setBrandId(brandEntity.getId());
                    goods.setBrandName(brandEntity.getName());
                    goods.setLogo(brandEntity.getLogo());
                }

                // 分类相关
                if (categoryEntity != null) {
                    goods.setCategoryId(categoryEntity.getId());
                    goods.setCategoryName(categoryEntity.getName());
                }

                /// 检索类型的规格参数及值
                List<SearchAttrValueVo> searchAttrs = new ArrayList<>();
                // 销售类型的检索类型的规格参数及值
                ResponseVo<List<SkuAttrValueEntity>> skuAttrResponseVo = mallPmsClient.querySearchAttrValuesBySkuIdAndCid(skuEntity.getId(), skuEntity.getCategoryId());
                List<SkuAttrValueEntity> skuAttrValueEntities = skuAttrResponseVo.getData();
                if (!CollectionUtils.isEmpty(skuAttrValueEntities)) {
                    searchAttrs.addAll(skuAttrValueEntities.stream().map(skuAttrValueEntity -> {
                        SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                        BeanUtils.copyProperties(skuAttrValueEntity, searchAttrValueVo);
                        return searchAttrValueVo;
                    }).collect(Collectors.toList()));
                }
                // 基本类型的检索类型的规格参数及值
                ResponseVo<List<SpuAttrValueEntity>> spuAttrResponseVo = mallPmsClient.querySearchAttrValuesBySpuIdAndCid(spuEntity.getId(), spuEntity.getCategoryId());
                List<SpuAttrValueEntity> spuAttrValueEntities = spuAttrResponseVo.getData();
                if (!CollectionUtils.isEmpty(spuAttrValueEntities)) {
                    searchAttrs.addAll(spuAttrValueEntities.stream().map(spuAttrValueEntity -> {
                        SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                        BeanUtils.copyProperties(spuAttrValueEntity, searchAttrValueVo);
                        return searchAttrValueVo;
                    }).collect(Collectors.toList()));
                }
                goods.setSearchAttrs(searchAttrs);

                return goods;
            }).collect(Collectors.toList());

            goodsRepository.saveAll(goodsList);
        }
        //确认消息
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
